package com.jacob.androidframe.database;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import com.thoughtworks.xstream.annotations.XStreamAlias;
import com.thoughtworks.xstream.annotations.XStreamAsAttribute;
import com.thoughtworks.xstream.annotations.XStreamImplicit;

@XStreamAlias("Database")
public class Database {
	
	@XStreamAsAttribute
	@XStreamAlias("DatabaseName")
	private String mDatabaseName;
	
	@XStreamAsAttribute
	@XStreamAlias("Version")
	private int mVersion;
	
	@XStreamImplicit
	private List<Table> mTableList;
	
	@XStreamImplicit
	private List<DatabaseUpgrate> mUpgrateSqlList;
	
	@XStreamImplicit
	@XStreamAlias("InitSql")
	private List<String> mInitSqlList;
	
	/**
	 * 私有化构造，使本类不能通过构造创建对象。
	 */
	private Database() {
		
	}
	
	/**
	 * 得到数据库名称
	 * 
	 * @return 数据库名称
	 */
	public String getDatabaseName() {
		return mDatabaseName;
	}

	/**
	 * 得到数据库版本
	 * @return 数据库版本
	 */
	public int getVersion() {
		return mVersion;
	}
	
	/**
	 * 通过实体类类名，得到对应的数据库表名。
	 * 
	 * @param pModelClassName 实体类的类名
	 * @return 数据库表名
	 */
	public String getTableName(String pModelClassName) {
		return getModelTableByModelClassName(pModelClassName).getTableName();
	}
	
	/**
	 * 通过数据库表名，得到对应的实体类的类名。
	 * 
	 * @param pModelClassName 数据库表名
	 * @return 实体类的类名
	 */
	public String getModelClassName(String pTableName) {
		return getModelTableByTableName(pTableName).getModelClassName();
	}
	
	/**
	 * 返回所有的表名
	 * 
	 * @return 包含所有表名的List
	 */
	public List<String> getAllTableName() {
		List<String> _AllTableNames = new ArrayList<String>();
		
		for (Table _ModelTable : mTableList) {
			_AllTableNames.add(_ModelTable.getTableName());
		}
		
		return _AllTableNames;
	}
	
	/**
	 * 返回某表的所有字段名
	 * 
	 * @param pTableName 表名
	 * @return 包含该表所有字段的List
	 */
	public List<String> getAllColumnName(String pTableName) {
		return getModelTableByTableName(pTableName).getAllColumnName();
	}
	
	/**
	 * 返回某表所有的字段及其Extra属性。
	 * 若pTableName等于null，或长度小于0，或未找到表，返回null；
	 * 若找到的表中没有字段，返回size()为0的Map对象。
	 * 
	 * @param pTableName 表名
	 * @return Map对象，Key为字段名，Value为Extra属性。
	 */
	public Map<String, String> getAllColumnExtra(String pTableName) {
		return getModelTableByTableName(pTableName).getAllColumnExtra();
	}

	
	/**
	 * 返回某表所有的字段及其对应的实体类成员变量。
	 * 若找到的表中没有字段，返回size()为0的Map对象。
	 * 
	 * @param pModelClass 实体类对象
	 * @return Map对象，Key为实体类成员变量名，Value为字段名。
	 */
	public Map<String, String> getFieldColumnMap(String pTableName) {
		return getModelTableByTableName(pTableName).getFieldColumnMap();
	}
	
	/**
	 * 返回某表所有的字段及其对应的实体类成员变量。
	 * 若找到的表中没有字段，返回size()为0的Map对象。
	 * 
	 * @param pModelClass 实体类对象
	 * @return Map对象，Key为字段名，Value为实体类成员变量名。
	 */
	public Map<String, String> getColumnFieldMap(String pTableName) {
		return getModelTableByTableName(pTableName).getColumnFieldMap();
	}
	
	/**
	 * 返回数据库的建库脚本。
	 * 
	 * @return List对象，其中包含所有的建库脚本。
	 */
	public List<String> getCreatDatabaseSql()
	{
		List<String> _SqlList = new ArrayList<String>();
		
		for (Table _Table : mTableList)
		{
			_SqlList.add(_Table.getCreatTableSql());
		}
		
		if (mInitSqlList!=null && mInitSqlList.size()>0)
		{
			for (String _String : mInitSqlList)
			{
				_SqlList.add(_String);
			}
		}
		
		return _SqlList;
	}
	
  /**
   * 得到数据库的升级脚本
   * 
   * @param pOldVersion 升级前的老版本号
   * @param pNewVersion 升级后的新版本号
   * @return List对象，其中包含从老版本升级到新版本的脚本。
   */
	public List<String> getUpgrateDatabaseSql(int pOldVersion, int pNewVersion)
  {
	  List<String> _UpgrateSqlList = new ArrayList<String>();
	  
	  while (pOldVersion != pNewVersion)
    {
	    for (DatabaseUpgrate _DatabaseUpgrate : mUpgrateSqlList)
	    {
	      if (pOldVersion == _DatabaseUpgrate.getOldVersion())
	      {
	        _UpgrateSqlList.addAll(_DatabaseUpgrate.getSqlList());
	        pOldVersion = _DatabaseUpgrate.getNewVersion();
	        break;
	      }
	    }
      
    }
	  
	  return _UpgrateSqlList;
    
  }
	
	private Table getModelTableByTableName(String pTableName) {
		Table _ModelTable = null;
		
		for (Table _tmpModelTable : mTableList) {
			if (pTableName.equals(_tmpModelTable.getTableName())) {
				_ModelTable = _tmpModelTable;
				break;
			} 
		}
		
		return _ModelTable;
	}
	
	private Table getModelTableByModelClassName(String pModelClassName) {
		Table _ModelTable = null;
		
		for (Table _tmpModelTable : mTableList) {
			if (pModelClassName.equals(_tmpModelTable.getModelClassName())) {
				_ModelTable = _tmpModelTable;
				break;
			} 
		}
		
		return _ModelTable;
	}

	
}
